#include "stdafx.h"
#include "curl_task.h"

namespace async_curl {
	curl_task::curl_task(curl_cb_t&& cb)
		:handle_(curl_easy_init()), cb_(std::forward<curl_cb_t>(cb)) {}

	curl_task::~curl_task() {
		curl_easy_cleanup(handle_);
	}

	CURL * curl_task::get_handler() {
		return handle_;
	}

	size_t curl_task::curl_write_cb(char * ptr, size_t size, size_t nmemb, void * userdata) {
		const auto len = size * nmemb;
		//auto * writeable = static_cast<writeable_task*>(userdata);
		auto * writeable = static_cast<curl_task_impl*>(userdata);
		writeable->append(ptr, len);
		return len;
	}

	curl_task_impl::curl_task_impl(curl_cb_t && cb)
		:curl_task(std::forward<curl_cb_t>(cb)), writeable_task(), ss_() {
#ifdef _DEBUG
		curl_easy_setopt(handle_, CURLOPT_VERBOSE, 1);
#endif
		curl_easy_setopt(handle_, CURLOPT_CAINFO, "cacert.pem");
		curl_easy_setopt(handle_, CURLOPT_NOPROGRESS, 1);
		curl_easy_setopt(handle_, CURLOPT_WRITEFUNCTION, &curl_task::curl_write_cb);
		curl_easy_setopt(handle_, CURLOPT_WRITEDATA, this);
		curl_easy_setopt(handle_, CURLOPT_PRIVATE, this);
	}

	void curl_task_impl::done() {
		int http_code = 0;
		curl_easy_getinfo(handle_, CURLINFO_RESPONSE_CODE, &http_code);
		if (cb_) {
			cb_(http_code, ss_.str());
		}
	}

	void curl_task_impl::done(CURLcode code, const char * msg) {
		if (cb_) {
			std::string msg_str(msg);
			cb_(code, msg_str);
		}
	}

	void curl_task_impl::append(char *s, std::size_t len) {
		ss_ << std::string(s, len);
	}
}
